package com.ruoyi.common.utils;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.springframework.util.StringUtils;

import java.io.File;

/**
 * 视频时长解析工具类
 * 支持本地视频文件的时长获取，自动处理路径格式和异常情况
 */
public class VideoDurationUtil {

    /**
     * 获取视频文件的时长（格式：HH:MM:SS）
     * @param fullVideoPath
     * @return 格式化的时长字符串，获取失败返回"00:00:00"
     */
    public static String getVideoDuration(String fullVideoPath) {
        // 1. 校验路径合法性
        if (!isValidVideoPath(fullVideoPath)) {
            return "00:00:00";
        }

        FFmpegFrameGrabber grabber = null;
        try {
            // 2. 初始化视频抓取器
            File videoFile = new File(fullVideoPath);
            grabber = new FFmpegFrameGrabber(videoFile);

            // 3. 根据文件后缀设置格式（提高兼容性）
            String fileName = videoFile.getName();
            setFormatByFileName(grabber, fileName);

            // 4. 设置超时和连接参数
            grabber.setOption("stimeout", "5000000"); // 5秒超时（单位：微秒）
            grabber.start();

            // 5. 计算时长（毫秒转秒）
            long durationMs = grabber.getLengthInTime();
            long totalSeconds = durationMs / 1000;

            // 6. 格式化时长为HH:MM:SS
            return formatDuration(totalSeconds);

        } catch (Exception e) {
            // 详细日志便于排查问题
            System.err.println("获取视频时长失败，路径：" + fullVideoPath + "，错误：" + e.getMessage());
            return "00:00:00";
        } finally {
            // 7. 确保资源释放
            if (grabber != null) {
                try {
                    grabber.stop();
                    grabber.close();
                } catch (Exception e) {
                    System.err.println("释放视频资源失败：" + e.getMessage());
                }
            }
        }
    }

    /**
     * 校验视频路径是否合法
     * @param videoPath 视频路径
     * @return 合法返回true，否则返回false
     */
    private static boolean isValidVideoPath(String videoPath) {
        // 路径为空校验
        if (StringUtils.isEmpty(videoPath)) {
            System.err.println("视频路径不能为空");
            return false;
        }

        // 文件存在性校验
        File videoFile = new File(videoPath);
        if (!videoFile.exists()) {
            System.err.println("视频文件不存在：" + videoPath);
            return false;
        }

        // 是否为文件校验
        if (!videoFile.isFile()) {
            System.err.println("路径不是有效文件：" + videoPath);
            return false;
        }

        // 视频文件后缀校验
        String fileName = videoFile.getName().toLowerCase();
        if (!fileName.endsWith(".mp4") && !fileName.endsWith(".avi")
                && !fileName.endsWith(".mov") && !fileName.endsWith(".flv")
                && !fileName.endsWith(".mkv")) {
            System.err.println("不支持的视频格式：" + fileName);
            return false;
        }

        return true;
    }

    /**
     * 根据文件名设置视频格式
     * @param grabber FFmpeg抓取器
     * @param fileName 文件名
     */
    private static void setFormatByFileName(FFmpegFrameGrabber grabber, String fileName) {
        String lowerFileName = fileName.toLowerCase();
        if (lowerFileName.endsWith(".mp4")) {
            grabber.setFormat("mp4");
        } else if (lowerFileName.endsWith(".avi")) {
            grabber.setFormat("avi");
        } else if (lowerFileName.endsWith(".mov")) {
            grabber.setFormat("mov");
        } else if (lowerFileName.endsWith(".flv")) {
            grabber.setFormat("flv");
        } else if (lowerFileName.endsWith(".mkv")) {
            grabber.setFormat("mkv");
        }
    }

    /**
     * 将总秒数格式化为HH:MM:SS
     * @param totalSeconds 总秒数
     * @return 格式化的时长字符串
     */
    private static String formatDuration(long totalSeconds) {
        // 处理负数情况
        if (totalSeconds < 0) {
            return "00:00:00";
        }

        long hours = totalSeconds / 3600;
        long minutes = (totalSeconds % 3600) / 60;
        long seconds = totalSeconds % 60;

        // 确保两位数格式（补零）
        return String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
}
